#include "Map.h"
#include <fstream>
#include <iostream>
#include <sstream>

/**
 * @brief 构造函数初始化角色位置为无效值
 */
Map::Map() : mapWidth_(0), mapHeight_(0), isLoaded_(false),
currentChapter_(0), playerRow_(-1), playerCol_(-1) {
}

/**
 * @brief 析构函数，清理资源
 */
Map::~Map() {
    clearMap();
}

// 设置角色初始位置
bool Map::setPlayerPosition(int row, int col) {
    if (isValidPosition(row, col) && isMovable(row, col)) {
        playerRow_ = row;
        playerCol_ = col;
        return true;
    }
    return false;
}

// 移动角色
bool Map::movePlayer(Direction dir) {
    if (!isLoaded_ || playerRow_ == -1 || playerCol_ == -1) {
        return false; // 地图未加载或角色位置未初始化
    }

    int newRow = playerRow_;
    int newCol = playerCol_;

    // 根据方向计算新位置
    switch (dir) {
    case Direction::UP:
        newRow--;
        break;
    case Direction::DOWN:
        newRow++;
        break;
    case Direction::LEFT:
        newCol--;
        break;
    case Direction::RIGHT:
        newCol++;
        break;
    default:
        return false;
    }

    // 检查新位置是否合法且可移动
    if (isValidPosition(newRow, newCol) && isMovable(newRow, newCol)) {
        playerRow_ = newRow;
        playerCol_ = newCol;
        return true;
    }
    return false;
}

// 获取角色当前位置
void Map::getPlayerPosition(int& row, int& col) const {
    row = playerRow_;
    col = playerCol_;
}

/**
 * @brief 加载指定章节的地图文件
 * @param chapterNumber 章节编号（1-18）
 * @return 加载成功返回true，失败返回false
 */
bool Map::loadMapFromFile(int chapterNumber) {
    // 检查章节编号有效性
    if (chapterNumber < 1 || chapterNumber > 18) {
        std::cerr << "Error: Chapter number must be between 1 and 18." << std::endl;
        return false;
    }

    // 清空当前地图数据
    clearMap();
    currentChapter_ = chapterNumber;

    // 构建文件名
    std::string characterMapFileName = "resources/chapter" + std::to_string(chapterNumber) + "map.txt";

    // 加载地图
    if (loadCharacterMap(characterMapFileName)) {
        isLoaded_ = true;
        // 初始化区域解锁状态，假设最大区域数为10
        unlockedAreas_.resize(10, false);
        std::cout << "Successfully loaded character map: " << characterMapFileName << std::endl;
        return true;
    }

    std::cerr << "Error: Failed to load map files for chapter " << chapterNumber << std::endl;
    return false;
}

/**
 * @brief 显示当前地图到控制台
 */
void Map::displayMap() const {
    if (!isLoaded_) {
        std::cout << "地图未加载" << std::endl;
        return;
    }

    for (int i = 0; i < mapHeight_; ++i) {
        for (int j = 0; j < mapWidth_; ++j) {
            // 角色位置显示'C'
            if (i == playerRow_ && j == playerCol_) {
                std::cout << 'C';
                continue;
            }

            // 其他位置根据类型显示对应字符
            int cellValue = mapData_[i][j];
            if (cellValue == static_cast<int>(CellType::EMPTY)) {
                std::cout << ' '; // 可移动区域
            }
            else if (cellValue == static_cast<int>(CellType::WALL)) {
                std::cout << '#'; // 墙壁
            }
            else if (cellValue >= static_cast<int>(CellType::INTERACTIVE)) {
                std::cout << '*'; // 交互元素
            }
        }
        std::cout << std::endl;
    }
}


/**
 * @brief 将字符转换为对应的地图元素类型
 * @param ch 输入字符
 * @return 对应的数字类型
 */
int Map::charToMapType(char ch) const {
    //0移动，1墙壁，2交互
    switch (ch) {
    case ' ': // 空格表示可移动区域
        return 0;
    case '2':
        return 2;
    case '3':
        return 3;
    case '4':
        return 4;
    case '5':
        return 5;
    default:
        // 其他字符视为墙壁
        return 1;
    }
}

/**
 * @brief 获取指定位置的地图元素类型
 * @param row 行坐标
 * @param col 列坐标
 * @return 返回该位置的元素类型
 */
Map::CellType Map::getCellType(int row, int col) const {
    if (!isValidPosition(row, col)) {
        return CellType::WALL; // 超出边界视为墙壁
    }

    int cellValue = mapData_[row][col];

    if (cellValue == 0) {
        return CellType::EMPTY;
    }
    else if (cellValue == 1) {
        return CellType::WALL;
    }
    else {
        return CellType::INTERACTIVE;
    }
}

/**
 * @brief 检查指定位置是否可以移动
 * @param row 行坐标
 * @param col 列坐标
 * @return 可移动返回true，否则返回false
 */
bool Map::isMovable(int row, int col) const {
    return (getCellType(row, col) == CellType::EMPTY) || (getCellType(row, col) == CellType::INTERACTIVE);
}

/**
 * @brief 检查指定位置是否为交互区域
 * @param row 行坐标
 * @param col 列坐标
 * @return 是交互区域返回true，否则返回false
 */
bool Map::isInteractive(int row, int col) const {
    return getCellType(row, col) == CellType::INTERACTIVE;
}

/**
 * @brief 获取地图高度
 * @return 地图行数
 */
int Map::getHeight() const {
    return mapHeight_;
}

/**
 * @brief 获取地图宽度
 * @return 地图列数
 */
int Map::getWidth() const {
    return mapWidth_;
}

/**
 * @brief 获取交互区域的类型编号
 * @param row 行坐标
 * @param col 列坐标
 * @return 交互类型编号（2-9），非交互区域返回0
 */
int Map::getInteractiveType(int row, int col) const {
    if (!isValidPosition(row, col)) {
        return 0;
    }

    int cellValue = mapData_[row][col];
    return (cellValue >= 2 && cellValue <= 9) ? cellValue : 0;
}

/**
 * @brief 清空当前地图数据
 */
void Map::clearMap() {
    mapData_.clear();
    unlockedAreas_.clear();
    mapWidth_ = 0;
    mapHeight_ = 0;
    isLoaded_ = false;
    currentChapter_ = 0;
}

/**
 * @brief 检查地图是否已加载
 * @return 已加载返回true，否则返回false
 */
bool Map::isMapLoaded() const {
    return isLoaded_;
}

/**
 * @brief 尝试加载字符格式的地图文件
 * @param fileName 文件名
 * @return 加载成功返回true，失败返回false
 */
bool Map::loadCharacterMap(const std::string& fileName) {
    std::ifstream file(fileName);
    if (!file.is_open()) {
        return false;
    }

    std::vector<std::string> lines;
    std::string line;

    // 读取所有行
    while (std::getline(file, line)) {
        lines.push_back(line);
    }
    file.close();

    if (lines.empty()) {
        return false;
    }

    // 确定地图尺寸
    mapHeight_ = static_cast<int>(lines.size());
    mapWidth_ = 0;

    // 找到最长的行作为地图宽度
    for (const std::string& currentLine : lines) {
        int lineLength = static_cast<int>(currentLine.length());
        if (lineLength > mapWidth_) {
            mapWidth_ = lineLength;
        }
    }

    // 初始化地图数据
    mapData_.resize(mapHeight_);
    for (int i = 0; i < mapHeight_; ++i) {
        mapData_[i].resize(mapWidth_, 0); // 默认填充为0（空）
    }

    // 转换字符数据为数字数据
    for (int row = 0; row < mapHeight_; ++row) {
        const std::string& currentLine = lines[row];
        int lineLength = static_cast<int>(currentLine.length());

        for (int col = 0; col < lineLength; ++col) {
            mapData_[row][col] = charToMapType(currentLine[col]);
        }

    }

    return true;
}

/**
 * @brief 检查坐标是否在地图范围内
 * @param row 行坐标
 * @param col 列坐标
 * @return 在范围内返回true，否则返回false
 */
bool Map::isValidPosition(int row, int col) const {
    return (row >= 0 && row < mapHeight_ && col >= 0 && col < mapWidth_);
}

/**
 * @brief 解锁指定区域
 * @param areaId 要解锁的区域ID
 * @return 解锁成功返回true，否则返回false
 */
bool Map::unlockArea(int areaId) {
    if (!isLoaded_) {
        std::cerr << "Error: Cannot unlock area - map not loaded." << std::endl;
        return false;
    }

    // 检查区域ID是否有效
    if (areaId <= 0 || areaId >= static_cast<int>(unlockedAreas_.size())) {
        std::cerr << "Error: Invalid area ID - " << areaId << std::endl;
        return false;
    }

    // 如果区域已解锁，直接返回true
    if (unlockedAreas_[areaId]) {
        return true;
    }

    // 标记区域为已解锁
    unlockedAreas_[areaId] = true;
    std::cout << "成功解锁区域: " << areaId << std::endl;

    // 应用区域解锁到地图
    applyAreaUnlock(areaId);

    return true;
}

/**
 * @brief 应用区域解锁到地图数据
 * @param areaId 已解锁的区域ID
 */
void Map::applyAreaUnlock(int areaId) {
    // 这里可以根据不同区域ID解锁地图的不同部分
    // 假设区域2解锁地图中的特定墙壁
    if (areaId == 2) {
        // 可以根据当前章节设置不同的解锁逻辑
        if (currentChapter_ == 1) {
            // 示例：解锁特定位置的墙壁
            if (isValidPosition(5, 5)) mapData_[5][5] = 0;
            if (isValidPosition(5, 6)) mapData_[5][6] = 0;
            std::cout << "章节1的区域2已解锁，新路径可用！" << std::endl;
        }
    }
    //因时间限制，只完成了前两章
}

/**
 * @brief 检查当前位置是否触发事件
 * @return 事件ID，0表示未触发任何事件
 */
int Map::checkEventTrigger() const {
    if (!isLoaded_ || playerRow_ == -1 || playerCol_ == -1) {
        return 0; // 地图未加载或角色位置未初始化，返回无事件
    }

    // 检查当前位置是否是交互元素
    if (isInteractive(playerRow_, playerCol_)) {
        return getInteractiveType(playerRow_, playerCol_);
    }

    // 检查周围区域是否有事件触发（示例：检查上下左右四个方向）
    const int directions[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    for (const auto& dir : directions) {
        int checkRow = playerRow_ + dir[0];
        int checkCol = playerCol_ + dir[1];

        if (isValidPosition(checkRow, checkCol) && isInteractive(checkRow, checkCol)) {
            // 返回交互元素类型作为事件ID
            return getInteractiveType(checkRow, checkCol);
        }
    }

    return 0;
}
